package NewTmas.FramesandPanels;

import NewTmas.Graphs.GraphVizGraph;
import NewTmas.Graphs.JGraphGenerated;
import taskmaster.auth.User;
import taskmaster.job.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: abhatnag
 * Date: 7/6/11
 * Time: 3:57 PM
 * To change this template use File | Settings | File Templates.
 */
public class JobGraphPanel
{


    public String job;
    public TaskBuilder tb;
    Task[] jobTasks;

    public Date date;

    public TablePanel collection_tp;
    JGraphGenerated jgraphObject;
    GraphVizGraph graphVizObj;


    public HashMap<String, TaskStatus> task_status;
    java.util.List<Dependency> dependencies;
    LinkedHashMap<String, Character> taskType;
    public HashMap<String, String> display_name;
    public TaskCollection tc;
    JButton openFilteredOutBtn;
    public User user;
    QueryParams joblimiters;
    public JDesktopPane dtp;
    public String lib;
    JLabel lblRunning, lblNot_yet_run, lblError, lblCompleted, lblnostatus;
    public IntFrame parentFrame;
    HashMap<String, String> Names = new HashMap<String, String>();
    Set<Task> alltasks = new HashSet<Task>();
    JobAllTasksCollection allTc;
    public HashMap<String, String> signoffMap;
    final JLabel lastrefreshedAt = new JLabel();


    public JLabel refreshRate = new JLabel();

    public JobGraphPanel(String jobname, Date date, TaskBuilder tb, User user, JDesktopPane dtp, TablePanel tablepanel, TaskCollection taskCollection, String selectedLib, IntFrame intFrame)
    {
        this.tb = tb;
        this.job = jobname;
        this.date = date;
        this.tc = taskCollection;
        this.collection_tp = tablepanel;
        this.user = user;
        this.dtp = dtp;
        this.parentFrame = intFrame;
        this.lib = selectedLib;
        this.signoffMap = intFrame.signoffMap;
        joblimiters = taskCollection.getLimiters();

        this.jobTasks = IntFrame.getTaskArrayforJob(taskCollection, this.job);

        //to get the basic job graph structure with all tasks in it
        allTc = new JobAllTasksCollection(user.getConnection(), job, lib);

        alltasks = allTc.alljobTasks;
        Names = allTc.defaultNames;
        this.dependencies = allTc.dependency_task;
        this.taskType = allTc.task_type;
        this.task_status = getStatus(jobTasks);
        this.display_name = getSpecialDisplayNames(jobTasks, Names);
    }

    public Object getGraphObj()
    {

        if (lib.equalsIgnoreCase("JGraphX"))
        {
            return jgraphObject;
        }

        if (lib.equalsIgnoreCase("GraphViz"))
        {
            return graphVizObj;

        }
        return null;
    }


    JPanel makeGraphPanel()
    {

        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());

        JPanel southPanel = new JPanel();
        southPanel.setLayout(new BoxLayout(southPanel, BoxLayout.X_AXIS));


        JPanel westPanel = new JPanel();
        westPanel.setLayout(new BoxLayout(westPanel, BoxLayout.PAGE_AXIS));
        westPanel.add(Box.createRigidArea(new Dimension(5, 15)));

        westPanel.add(lblCompleted = new JLabel());
        lblCompleted.setBackground(Color.green);
        lblCompleted.setOpaque(true);
        westPanel.add(Box.createRigidArea(new Dimension(5, 15)));
        westPanel.add(lblError = new JLabel());
        lblError.setBackground(Color.RED);
        lblError.setOpaque(true);

        westPanel.add(Box.createRigidArea(new Dimension(5, 15)));
        westPanel.add(lblRunning = new JLabel());
        lblRunning.setBackground(Color.GRAY);
        lblRunning.setOpaque(true);
        westPanel.add(Box.createRigidArea(new Dimension(5, 15)));
        westPanel.add(lblNot_yet_run = new JLabel());
        lblNot_yet_run.setBackground(Color.white);
        lblNot_yet_run.setOpaque(true);
        westPanel.add(Box.createRigidArea(new Dimension(5, 15)));

        lblnostatus = new JLabel("Filtered out");
        westPanel.add(lblnostatus);
        lblnostatus.setBackground(Color.decode("#CAE1FF"));
        lblnostatus.setOpaque(true);

        westPanel.add(Box.createRigidArea(new Dimension(5, 15)));
        openFilteredOutBtn = new JButton("Open Job NoFilters");
        westPanel.add(openFilteredOutBtn);
        openFilteredOutBtn.setVisible(false);

        openFilteredOutBtn.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                new IntFrame(new String[]{job}, date, new String[0], new int[0], lib, user, tb, dtp, signoffMap, parentFrame.width, parentFrame.height);
            }
        });


        int cntFilteredout = setTaskCountLabels(task_status, allTc.alljobTasks);
        if (cntFilteredout > 0)
        {
            openFilteredOutBtn.setVisible(true);
        }

        lastrefreshedAt.setForeground(Color.blue);

        refreshRate.setForeground(Color.BLUE);

        southPanel.add(lastrefreshedAt);
        southPanel.add(Box.createRigidArea(new Dimension(10, 5)));
        southPanel.add(refreshRate);

        southPanel.add(Box.createRigidArea(new Dimension(50, 5)));
        southPanel.add(new JLabel("Shapes:  "));
        southPanel.add(Box.createRigidArea(new Dimension(10, 5)));

        southPanel.add(new JLabel("System: Ellipse"));
        southPanel.add(Box.createRigidArea(new Dimension(15, 5)));
        if (lib.equals("JGraphX"))
        {
            southPanel.add(new JLabel("External:CLoud"));
        } else
        {
            southPanel.add(new JLabel("External:Parallelogram"));

        }
        southPanel.add(Box.createRigidArea(new Dimension(15, 5)));
        southPanel.add(new JLabel("Verify: Diamond"));
        southPanel.add(Box.createRigidArea(new Dimension(15, 5)));

        southPanel.add(new JLabel("Execute: Rectangle"));
        southPanel.add(Box.createRigidArea(new Dimension(15, 5)));

        southPanel.add(new JLabel(" Interactive : Triangle"));
        southPanel.add(Box.createRigidArea(new Dimension(15, 5)));
        southPanel.add(new JLabel("Cron: Hexagon "));


        mainPanel.add(southPanel, BorderLayout.SOUTH);

        if (lib.equalsIgnoreCase("JGraphX"))
        {
            jgraphObject = new JGraphGenerated(dependencies, task_status, taskType, display_name, this);
            mainPanel.add(jgraphObject.graphComponent);
        } else
        {
            graphVizObj = new GraphVizGraph(dependencies, task_status, taskType, display_name, this, parentFrame.width, parentFrame.height);
            mainPanel.add(graphVizObj.jsp);
        }

        mainPanel.add(westPanel, BorderLayout.WEST);

        return mainPanel;
    }


    public HashMap<String, TaskStatus> getStatus(Task[] jobTasks)
    {
        try
        {
            HashMap<String, TaskStatus> task_status = new HashMap<String, TaskStatus>();
            Task[] alltasks = jobTasks;
            for (int i = 0; i < alltasks.length; i++)
            {
                if (alltasks[i].getJobTag().equalsIgnoreCase(job))
                {
                    task_status.put(alltasks[i].getTaskTag(), new TaskStatus(alltasks[i].getStatusId()));

                }
            }

            return task_status;
        }
        catch (Exception e)
        {
            System.out.println("error getting status from DB");
            e.printStackTrace();
        }
        return null;

    }


    public int setTaskCountLabels(HashMap<String, TaskStatus> task_status, HashSet<Task> alljobTasks)
    {

        int cntRunning = 0, cntNot_Yet_Run = 0, cntCompleted = 0, cnt_Error = 0, cntFilteredout = 0;
        for (Map.Entry<String, TaskStatus> e : task_status.entrySet())
        {

            if (e.getValue().getStatusCategory().equalsIgnoreCase("notYetRun"))
            {
                cntNot_Yet_Run++;
            }
            if (e.getValue().getStatusCategory().equalsIgnoreCase("completed")) {cntCompleted++;}

            if (e.getValue().getStatusCategory().equalsIgnoreCase("Error")) {cnt_Error++;}

            if (e.getValue().getStatusCategory().equalsIgnoreCase("Running")) {cntRunning++;}


        }
        List<Task> list = Arrays.asList(jobTasks);
        HashSet<String> set = new HashSet<String>();
        for (Task task : list)
        {
            set.add(task.getKey());
        }

        for (Task t : alljobTasks)
        {
            if (!set.contains(t.getKey()))
            {

                cntFilteredout++;
            }

        }


        lblCompleted.setText("#Completed : " + cntCompleted);
        lblError.setText("#Error : " + cnt_Error);
        lblNot_yet_run.setText("#Not Yet Run : " + cntNot_Yet_Run);
        lblRunning.setText("#Running : " + cntRunning);
        lblnostatus.setText("#Filtered Out : " + cntFilteredout);

        return cntFilteredout;
    }


    public HashMap<String, String> getSpecialDisplayNames(Task[] jobTasks, HashMap<String, String> Names)
    {
        HashMap<String, String> newNames = new HashMap<String, String>();
        newNames.putAll(Names);
        for (Task t : jobTasks)
        {

            newNames.put(t.getTaskTag(), Names.get(t.getTaskTag()));
            if (t.isRunning())
            {
                StringBuffer newName = new StringBuffer(Names.get(t.getTaskTag()));
                if (lib.equalsIgnoreCase("JGraphX"))
                {
                    newName.append("\n" + String.valueOf((int) t.getPercentFinishedVsLast()) + "%");
                } else
                {
                    newName.append("\\n" + String.valueOf((int) t.getPercentFinishedVsLast()) + "%");
                }
                newNames.put(t.getTaskTag(), newName.toString());

            }


        }

        return newNames;
    }


    public void refreshGraph(TaskCollection newTC)
    {

        try
        {
            final Task[] tasks = IntFrame.getTaskArrayforJob(newTC, this.job);
            display_name = getSpecialDisplayNames(tasks, Names);
            task_status = getStatus(tasks);
            int cntFilteredout = setTaskCountLabels(task_status, allTc.alljobTasks);
            if (cntFilteredout > 0)
            {
                openFilteredOutBtn.setVisible(true);
            }

            if (jgraphObject != null)
            {
                jgraphObject.display_name = display_name;
                jgraphObject.task_status = task_status;
            }
            if (graphVizObj != null)
            {
                graphVizObj.display_name = display_name;
                graphVizObj.task_status = task_status;
            }

        } catch (Exception e)
        {
            JOptionPane.showMessageDialog(null, "Possible Problem refreshing the graph: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
            //e.printStackTrace();
        }

        if (lib.equalsIgnoreCase("JGraphX"))
        {
            jgraphObject.refreshGraphObject();
        } else
        {
            graphVizObj.refreshGraphViz();
        }

    }


}
